#include <iostream>

class Log
{
public:
    static Log &getInstance()
    {
        static Log instance;
        return instance;
    }

    template <typename... Args>
    void log(const std::string &format, Args... args)
    {
        int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
        if (size_s <= 0)
        {
            throw std::runtime_error("Error during formatting.");
        }
        auto size = static_cast<size_t>(size_s);
        std::unique_ptr<char[]> buf(new char[size]);
        std::snprintf(buf.get(), size, format.c_str(), args...);
        std::string output = std::string(buf.get(), buf.get() + size - 1);
        this->addLog(output);
    }

    void log(std::string str)
    {
        this->addLog(str);
    }

private:
    Log(){};
    Log(Log &) = delete;
    void operator=(Log const &) = delete;
    static Log *instancePtr;
    void addLog(std::string output)
    {
        std::cout << "Log: " << output << std::endl;
    }
};
